/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vadung.contragame2d;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import sample_1.Scanner; 

/**
 *
 * @author dung.voanh
 */
public final class GameLayerManager {

    private static GameLayerManager s_gameLayerManager;

    private int m_rows;
    private int m_columns;
    private int m_tiledWidth;
    private int m_tiledHeight;
    //private Vector m_imageList;
    private Vector m_layerList;
    //Position (x, y) top-left to draw windows action
    private int m_iPositionX;
    private int m_iPositionY;

    public int GetPositionX() {
        return m_iPositionX;
    }

    public int GetPositionY() {
        return m_iPositionY;
    }

    public int GetTiledWidth() {
        return m_tiledWidth;
    }

    public int GetTiledHeight() {
        return m_tiledHeight;
    }

    public int GetMapWidth() {
        return m_columns * m_tiledWidth;
    }

    public int GetMapHeight() {
        return m_rows * m_tiledHeight;
    }

    public static GameLayerManager GetInstance() {
        if (s_gameLayerManager == null) {
            s_gameLayerManager = new GameLayerManager();
        }
        return s_gameLayerManager;
    }

    public GameTiledLayer GetLayer(int index) {
        if (index >= 0 && index < m_layerList.size()) {
            return (GameTiledLayer) m_layerList.elementAt(index);
        }
        return null;
    }

    public GameTiledLayer GetFirstLayer(String nameType) {
        synchronized (m_layerList) {
            GameTiledLayer layerTemp;
            for (int i = 0; i < m_layerList.size(); i++) {
                layerTemp = (GameTiledLayer) m_layerList.elementAt(i);
                if (layerTemp.m_strNameType.equalsIgnoreCase(nameType)) {
                    return layerTemp;
                }
            }
        }
        return null;
    }

    public void SetViewWindows(int posX, int posY) {
        m_iPositionX = posX;
        m_iPositionY = posY;
    }

    /**
     * Moving window display
     *
     * @param deltaX : move delta x direction
     * @param deltaY : move delta y direction
     */
    public void MoveViewWindows(int deltaX, int deltaY) {
        int xTemp = m_iPositionX + deltaX;
        int yTemp = m_iPositionY + deltaY;

        if (xTemp >= 0 && xTemp <= GetMapWidth()) {
            m_iPositionX = xTemp;
        }

        if (yTemp >= 0 && yTemp <= GetMapHeight()) {
            m_iPositionY = yTemp;
        }
    }

    public void AddLayer(GameTiledLayer layer) {
        m_layerList.addElement(layer);
    }

    public void RemoveLayer(GameTiledLayer layer) {
        m_layerList.removeElement(layer);
    }

    private GameLayerManager() {
        //m_imageList = new Vector();
        m_layerList = new Vector();
        m_iPositionX = 0;
        m_iPositionY = 0;
    }

    /**
     * Remove all GameTiledLayer is handling and add new GameTiledLayer from
     * file
     *
     * @param file
     */
    public void Load(String file) {
        m_layerList.removeAllElements();
        SetViewWindows(0, 0);

        System.out.println("************LOAD MAP************");
        //Loade new memory
        InputStream inputStream = getClass().getResourceAsStream(file);
        Scanner scanner = new Scanner(inputStream);

        String strElement = "";
        while (scanner.hasNext()) {
            try { 
                if (strElement.equalsIgnoreCase("#ROWS")) {
                    m_rows = scanner.getNextInt();
                    strElement = "";
                    
                } else if (strElement.equalsIgnoreCase("#COLUMNS")) {
                    m_columns = scanner.getNextInt();
                    strElement = "";
                    
                } else if (strElement.equalsIgnoreCase("#TITE_WIDTH")) {
                    m_tiledWidth = scanner.getNextInt();
                    strElement = "";
                    
                } else if (strElement.equalsIgnoreCase("#TILE_HEIGHT")) {
                    m_tiledHeight = scanner.getNextInt();
                    strElement = "";
                    
                } else if (strElement.equalsIgnoreCase("#TILE_LAYER")) { 
                    strElement = LoadLayer(scanner);

                } else if (strElement.equalsIgnoreCase("#OBJECTS")) {
                    strElement = LoadObject(scanner);

                } else {
                    strElement = "";
                }

                if (strElement.equals("")) {
                    strElement = scanner.getNext();
                }

            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }

    private String LoadLayer(Scanner scanner) {
        System.out.println("************LOAD TILEDLAYER************");
        int id = 0;
        int imageID = 0;
        GameTiledLayer gameTileLayerTemp = null;

        String strElement = "";
        while (scanner.hasNext()) {
            try {
                strElement = scanner.getNext();

                if (strElement.startsWith("#")) {
                    break; //End read layer
                } else if (strElement.equalsIgnoreCase("ID")) {  //Element ID must on top in all attribute 
                    gameTileLayerTemp = new GameTiledLayer();
                    id = scanner.getNextInt();
                } else if (strElement.equalsIgnoreCase("TYPE")) {
                    gameTileLayerTemp.SetNameType(scanner.getNext());
                } else if (strElement.equalsIgnoreCase("IMAGE_TILESET_ID")) {
                    imageID = scanner.getNextInt();
                } else if (strElement.equalsIgnoreCase("DATA")) { //Element DATE must on bottom in all attribute 
                    //Read data for map
                    int lenData = m_rows * m_columns;
                    int aiDataMap[] = new int[lenData];
                    for (int i = 0; i < lenData; i++) {
                        aiDataMap[i] = scanner.getNextInt();
                    }

                    Image imgTileset = ResourceManager.GetInstance().GetImage(imageID);
                    GameTiledLayer layer = gameTileLayerTemp;
                    layer.Load(imgTileset, m_tiledWidth, m_tiledHeight, aiDataMap, m_rows, m_columns);

                    AddLayer(layer);
                    gameTileLayerTemp = null;
                }

            } catch (Exception e) {
                System.out.println("ERROR: LOAD LAYER " + id);
                System.out.println(e.getMessage());
                //e.printStackTrace();
            }
        }
        return strElement;
    }

//    
    private String LoadObject(Scanner scanner) {
        System.out.println("************LOAD OBJECT************");
        String strElement = "";
        int typeObject = 0;
        int x = 0;
        int y = 0;
        
        while (scanner.hasNext()) {
            try { 
                scanner.getNext();
                typeObject = scanner.getNextInt();
                
                scanner.getNext();
                x = scanner.getNextInt();
                
                scanner.getNext();
                y = scanner.getNextInt();
                
                MyObject.GetInstance().Add(typeObject, x, y); 
                
            } catch (Exception e) {
                System.out.println("ERROR: LOAD OBJECT - Type =  " + typeObject + ", x = " + x + ", y = " + y);
                System.out.println(e.getMessage());
                //e.printStackTrace();
            }
        }
        return strElement;
    }
    
    public void Update(long deltaTime) {
    }

    public void Rendder(Graphics g) {
        for (int i = 0; i < m_layerList.size(); i++) {
            synchronized (m_layerList) {
                ((GameTiledLayer) m_layerList.elementAt(i)).Render(g, m_iPositionX, m_iPositionY);
            }
        }
    }

    public boolean CheckCollision(int indexALyer, int posX, int posY) {
        int row = posY / m_tiledHeight;
        int column = posX / m_tiledWidth;

        GameTiledLayer layerTemp = GetLayer(indexALyer);
        if (layerTemp != null) {
            int valueTiled = layerTemp.GetDaTa(row, column);
            if (valueTiled != 0) {
                return true;
            }
        }
        return false;
    }

    public boolean CheckCollision(int indexALyer, int posX, int posY, int width, int height) {
        if (CheckCollision(indexALyer, posX, posY + height)) {
            return true;
        }
        return CheckCollision(indexALyer, posX + width, posY + height);
    }

    public boolean IsOutMap(int posXOnMap, int posYOnMap) {
//        if(posXOnMap < m_iPositionX || posXOnMap > GetMapWidth()
//           || posYOnMap < m_iPositionY || posYOnMap > GetMapHeight()){            
//            return true;            
//        }
        int row = posYOnMap / m_tiledHeight;
        int column = posXOnMap / m_tiledWidth;

        if (row < 0 || row >= m_rows || column < 0 || column >= m_columns) {
            return true;
        }
        return false;
    }

    public boolean IsOutWindowView(int posXOnMap, int posYOnMap) {
        if (posXOnMap < m_iPositionX || posXOnMap > m_iPositionX + Midlet.s_canGame.getWidth()
                || posYOnMap < m_iPositionY || posYOnMap > m_iPositionY + Midlet.s_canGame.getHeight()) {
            return true;
        }
        return false;
    }

    public boolean IsOutWindowView(int posXOnMap, int posYOnMap, int width, int height) {
        if (IsOutWindowView(posXOnMap, posYOnMap)) {
            return true;
        }
        return IsOutWindowView(posXOnMap + width, posYOnMap + height);
    }

}
